package edu.udo.sopra10.chaturaji.entities.pieces;

import static edu.udo.sopra10.chaturaji.util.ExceptionUtil.assertNotNull;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.unmodifiableCollection;

import java.util.ArrayList;
import java.util.Collection;

import edu.udo.sopra10.chaturaji.entities.Player;
import edu.udo.sopra10.chaturaji.entities.Square;
import edu.udo.sopra10.chaturaji.entities.coordinates.Movement;
import edu.udo.sopra10.chaturaji.entities.coordinates.Position;
import edu.udo.sopra10.chaturaji.util.CloneUtil;

/**
 * An elephant is one of the Chaturaji {@link Piece}s. It is worth four points.
 * Players start with a single elephant in the right central square of their
 * second row. Elephants move an arbitrary number of squares into any direction,
 * although they can not jump over pieces, capturing opposing pieces they land
 * on.
 * 
 * @author Simon Dierl
 */
public final class Elephant extends Piece {
	/**
	 * The basic direction an elephant is capable of moving into.
	 */
	private static final Collection<Movement> BASIC_MOVEMENTS = unmodifiableCollection(asList(
			new Movement((byte) -1, (byte) 0), new Movement((byte) 1, (byte) 0),
			new Movement((byte) 0, (byte) -1), new Movement((byte) 0, (byte) 1)));

	/**
	 * Create a new {@link Elephant}.
	 * 
	 * @param owner
	 *            the player owning the elephant, must not be {@code null}.
	 * @param square
	 *            the square the elephant stands on, may be {@code null} to
	 *            indicate a captured piece.
	 */
	public Elephant(final Player owner, final Square square) {
		super((byte) 4, owner, square);
		this.pieceValue = 50;
	}

	@Override
	public Actions getPossibleActions(final Square[][] board,
			final Position currentPosition) {
		assertNotNull(board, "board");
		assertNotNull(currentPosition, "currentPosition");

		final Collection<Position> possibleMoves = new ArrayList<Position>(14);
		final Collection<Position> possibleCaptures = new ArrayList<Position>(4);
		final Collection<Position> possiblePawnPromotions = emptyList();

		for (final Movement basicMovement : BASIC_MOVEMENTS) {
			final Position movePosition = CloneUtil.clone(currentPosition);
			try {
				while (true) {
					movePosition.shift(basicMovement);
					final Piece piece = board[movePosition.getX()][movePosition
							.getY()].getPiece();
					if (piece == null) {
						possibleMoves.add(CloneUtil.clone(movePosition));
					} else {
						if (!piece.getOwner().equals(owner)) {
							possibleCaptures.add(CloneUtil.clone(movePosition));
						}
						break;
					}
				}
			} catch (final IllegalArgumentException e) {
				continue;
			}
		}

		return (new Actions(possibleMoves, possibleCaptures, null,
				possiblePawnPromotions));
	}
}
